from abc import ABC, abstractmethod
from .Pos import Pos
import json


class HistoryEntry(ABC):
    def __init__(self, player: int, type: str):
        self.player = player
        self.type = type

    @abstractmethod
    def to_str(self):
        return "UnknownEvent"

    @abstractmethod
    def to_json(self):
        return json.dumps({})


class MoveEvent(HistoryEntry):
    def __init__(self, player: int, which: str, where: Pos, to: Pos):
        super().__init__(player, "move")
        self.which = which
        self.where = where
        self.to = to

    def to_str(self):
        return f"Player #{self.player}: {self.which} from {str(self.where)} to {str(self.to)}"

    def to_json(self):
        return json.dumps({'player': self.player,
                          'type': 'move',
                           'chess': {
                               'type': self.which,
                               'pos': str(self.where)
                           },
                           'dest': str(self.to),
                           'str': self.to_str()})


class KillEvent(HistoryEntry):
    def __init__(self, player: int, killer: str, killer_pos: Pos, victim: str, victim_pos: Pos):
        super().__init__(player, "kill")
        self.killer = killer
        self.killer_pos = killer_pos
        self.victim = victim
        self.victim_pos = victim_pos

    def to_str(self):
        return f"Player #{self.player}: {self.killer} at {str(self.killer_pos)} kills {self.victim} at {str(self.victim_pos)}"

    def to_json(self):
        return json.dumps({'player': self.player,
                          'type': 'kill',
                           'killer': {
                               'type': self.killer,
                               'pos': str(self.killer_pos)
                           },
                           'victim': {
                               'type': self.victim,
                               'pos': str(self.victim_pos)
                           },
                           'str': self.to_str()})


class SkillEvent(HistoryEntry):
    def __init__(self, player: int, chess: type, pos: Pos, what: str):
        super().__init__(player, "skill")
        self.chess = chess
        self.pos = pos
        self.what = what

    def to_str(self):
        return f"Player #{self.player}: {self.chess} at {str(self.pos)} uses skill {self.what}"

    def to_json(self):
        return json.dumps({'player': self.player,
                          'type': 'skill',
                           'user': {
                               'type': self.chess,
                               'pos': str(self.pos)
                           },
                           'str': self.to_str()})


class TakebackEvent(HistoryEntry):
    def __init__(self, player):
        super().__init__(player, "takeback")

    def to_str(self):
        return f"Player {self.player}: take back"

    def to_json(self):
        return json.dumps({'player': self.player, 'type': 'takeback',
                          'str': self.to_str()})
